import { ATeamCombat } from "GameLoop/WorldState/EntityManager/Entitys";
import { PositionHelper } from "utils/position/PositionHelper";
import { IDefendStrategy } from "./Base";
import { ETaskState } from "GameLoop/DecisionMaking/TaskDeclare/type";
import { getRoleConfig } from "utils/constants/bodyconstant";
import { CreepAbilityHelper } from "utils/creep/CreepAbilityHelper";
import { WhiteListManager } from "GameLoop/WorldState/EngineConfig/WhiteListManager";
import { UtilsHelper } from "utils/position/UtilsHelper";

/**
 * 过道房的资源防守
 */
export class DefendStrategy4 extends IDefendStrategy
{
    public assignTarget(room:Room,task:ITask<ITeamTaskData<"defend">>,team:ATeamCombat[],creeps:Creep[]):   ETaskState 
    {
        const workroom = Game.rooms[task.data.room];
       // throw new Error("Method not implemented.");
       const goal = this.getMoveGoal(task.data.room,workroom);
        if(workroom)
        {
            // 1.查找当前房间
            // 2.然后查找我当前要攻击PowerBank            
            // 3.更新防守区域
            const pb = Game.getObjectById(task.data.arg.structures[0]) as StructurePowerBank;
            if(pb)
            {
                task.data.arg.defendRange=[{pos:pb.pos,range:6}];
            }
            if(pb)
            {
                 // 4.检测出运输工的时机,同时统计pb的掉血速度
                if(room.canExecute(101)||!task.data.arg.pbarg)
                {
                    task.data.arg.pbarg ={damage: _.sum(team,e=>e.getAttackAbility)};
                }

                // 计算出运输的时机.
                if(task.data.arg.pbarg.damage*(task.data.cost+200)>pb.hits)
                {
                    if(task.data.creepRequired.length == 0)
                    {
                        // 要出运输爬了
                        // 根据pb的存量计算需要的爬数量
                        const bodyconfig = getRoleConfig('porter',room.controller!.level);
                        
                        const carry = _.sum(bodyconfig.body,e=>e[0] ==CARRY?e[1]*50:0);
                        const carryer_count = Math.ceil( pb.power/carry);
                        task.data.creepRequired=[
                            [{
                                Role:"porter",
                                body:bodyconfig.body,
                            },carryer_count,carryer_count]
                        ]
                    }
                    // 小队的需求改为1队
                    task.data.required.forEach(e=>e[1] =1);
                }
            }
            else 
            {
                // 没有pb则检测房间是否有power。
                // 没有pb了则不用再出小队了,要打架也是用现成的打
                task.data.required=[];
                
                const ruin_pos = task.data.arg.defendRange?task.data.arg.defendRange[0]?.pos:undefined;
                if(ruin_pos)
                {
                    if( _.sum( creeps,e=>e.store.getUsedCapacity(RESOURCE_POWER)) ==0)
                    {
                        if( (workroom.lookForAt(LOOK_RUINS, ruin_pos.x,ruin_pos.y).length ==0 &&workroom.lookForAt(LOOK_RESOURCES, ruin_pos.x,ruin_pos.y).length ==0) )
                        {
                            task.data.creepRequired=[];
                            // 没有power,没有废墟。且没有正在运输则表示运完了
                            return ETaskState.Complete;
                        }
                    }
                }
                else 
                {
                    task.data.creepRequired=[];
                    return ETaskState.Complete;
                }
                
                
            }

            // 任务没有完成的情况下,
            // 5.检测周围敌方单位，转火
            if(task.data.arg.defendRange)
            {
                // 重新更新攻击目标
                const targets = workroom.getHostileCreeps().filter(e=>
                    {
                        task.data.arg.defendRange!.some(r=>PositionHelper.Distance(r.pos, e.pos)<=r.range)
                    });
                for(let i=0;i< task.data.arg.enemy.length;)
                {
                    const obj = Game.getObjectById(task.data.arg.enemy[i]);
                    if(!obj || task.data.arg.defendRange!.some(r=>PositionHelper.Distance(r.pos, obj.pos)>r.range+4))
                    {
                        // 跑到4格范围内
                        task.data.arg.enemy.splice(i,1);
                    }
                    else 
                    {
                        if(!targets.find(e=>e.id == obj.id))
                        {
                            // 找不到
                            targets.splice(0,0,obj);
                        }
                        i++;
                    }
                }
                task.data.arg.enemy = targets.map(e=>e.id);
                task.data.arg.structures = task.data.arg.structures.filter(e=>Game.getObjectById(e));
                this.updateTeamAroundHostile(team,targets);
                this.updateCreepAroundHostile(creeps,targets);
                if(task.data.arg.enemy.length>0)
                {
                    this.setCreepTactic(creeps,{goal:goal,type:2,targets:[PositionHelper.getObjectRef(targets[0])]},task.data.room,this.correctCreep);
                    this.setTeamTractic(team,{goal:goal,type:2,targets:[PositionHelper.getObjectRef(targets[0])]},task.data.room,this.correctTeam);
                }else  if(task.data.arg.structures.length>0) 
                {
                    
                    this.setCreepTactic(creeps,{goal:goal,type:2,targets:[PositionHelper.getObjectRef(task.data.arg.structures[0])]},task.data.room);
                    this.setTeamTractic(team,{goal:goal,type:2,targets:[PositionHelper.getObjectRef(task.data.arg.structures[0])]},task.data.room,this.teamCorrect);
                }
            }
            else 
            {
                const pbs = workroom.find(FIND_STRUCTURES,{filter:STRUCTURE_POWER_BANK}) as StructurePowerBank[];
                // 如果没有这个参数。可能已经结束了
                if(pbs.length==0)
                {
                    return ETaskState.Complete;
                }
                else 
                {
                    task.data.arg.structures = pbs.map(e=>e.id);
                }
                workroom.log(`error`,`PB 任务未初始化 防守范围`)
            }
        }
        else
        {
            // 1.首先先移动到目标房间。
        }
        return ETaskState.Running
    }

    private teamCorrect(team:ATeamCombat,workroom:string,pos:IAttackTactic):IMoveGoal|undefined
    {
        if(pos.targets.length && Game.rooms[workroom])
        {
            if(!team.getAnchor()|| team.getAnchor().distance(pos.targets[0]) <=1)
            {
                return undefined;
            }
            if(!PositionHelper.getFreeSpace(pos.targets[0]).some(
                e=>PositionHelper.lookFor(LOOK_CREEPS,e).filter(c=>(c.my && c.ActiveRole() == "idaRed") || !c.my).length == 0 ))
            {
                // 没有空位了
                
                return {
                    pos:PositionHelper.findRingOfValidPosition(pos.targets[0],2)[0],range:2} 
            }
        }
        return undefined;
    }
}

